const HIGH_LIGHT_MODE = {
  NORMAL: 0,
  KRC: 1
};
class ZegoLyricView {
  constructor() {
    // 所有字体颜色
    this.mDefaultColor = "#CCFFFFFF"; // 默认字体颜色
    this.mHighLightColor = "#ff3571"; // 当前播放位置的颜色
    // private mHighLightPath = new Path();
    // 字体大小
    this.highLightFontSize = 16;
    this.defaultFontSize = 14;
    //设置长歌词从屏幕1/mScale处开始滚动到结束停止，当前默认为长歌词播放到1/3之一就开始滚动。
    this.mScale = 3;
    this.mDefaultHint = "ZegoLyricView";
    this.mInitText = "LyricView";
    this.mCurrentPlayLine = 0;
    this.mLineCount = 0;
    /**
     * 歌词高亮的模式
     */
    this.mode = HIGH_LIGHT_MODE.KRC;
    this.customDefaultFontStyle = "";
    this.customHighLightFontStyle = "";
    this.customLineStyle = "";
    this.mCurrentTimeMillis = 0;
    // private OnLyricLineFinishedListener mOnLyricLineFinishedListener;
    this.mLineFeedPosition = -1;
    this.id = "zg-lyrics-view_" + new Date().getTime();
    this.container = null;
    this.currentTime = 0;
    this.__freq = 10; // 滚动频率（ms）
    this.__fraction = 0 / 5; // 高亮显示行在歌词显示区域中的固定位置百分比
    this.currentLine = 0;
    const showBox = (this.showBox = document.createElement("div"));
    showBox.setAttribute("style", "width:100%;height:100%;overflow:scroll;");
    showBox.setAttribute("id", this.id);
    showBox.setAttribute("class", `zg-lyrics-view`);
    const ul = (this.lyricsUl = document.createElement("ul"));
    showBox.append(ul);
  }
  /**
   * 需要先调用 setupLyric 设置歌词数据后，再调用 setCurrentTimeMillis(long current) 方法，才能将歌词展示出来
   * @param lrc 歌词数据模型
   */
  setupLyric(lrc) {
    let _a;
    // resetView();
    if (!(lrc === null || lrc === void 0 ? void 0 : lrc.lines))
      throw "lrc format error";
    const mLyricInfo = (this.mLyricInfo = lrc);
    this.mCurrentPlayLine = -1;
    if (lrc != null) {
      if (
        !((_a = mLyricInfo.lines[0]) === null || _a === void 0
          ? void 0
          : _a.words)
      ) {
        // 逐行歌词数据源
        this.mode = HIGH_LIGHT_MODE.NORMAL;
      } else {
        // 逐字歌词数据源
        this.mode = HIGH_LIGHT_MODE.KRC;
      }
      this.mLineCount = this.mLyricInfo.lines.length;
    } else {
      throw "lrc error";
    }
    if (this.lyricsUl && lrc.lines.length > 0) {
      const linesHtml = lrc.lines.reduce((result, lineItem, lineIndex) => {
        let lineHtml = "";
        if (lineItem) {
          if (lineItem.words && this.mode === HIGH_LIGHT_MODE.KRC) {
            const lineHtmlContent = lineItem.words.reduce(
              (lineResult, wordItem, wordIndex) => {
                if (wordItem) {
                  lineResult += `<span class="zg-lrc-word zg-lrc-word-${wordIndex}">${wordItem.word}</span>`;
                }
                return lineResult;
              },
              ""
            );
            lineHtml = `<p class="zg-lrc-line zg-lrc-line-${lineIndex}">${lineHtmlContent}</p>`;
          } else {
            lineHtml = `<p class="zg-lrc-line zg-lrc-line-${lineIndex}">${lineItem.content}</p>`;
          }
          return (result += lineHtml);
        }
        return result;
      }, "");
      this.lyricsUl.innerHTML =
        linesHtml + `<style id="${this.id}_style"></style>`;
      this.updateStyle();
      console.log("挂载html", this.lyricsUl);
    }
    // clearLyricLineFeed();
    // invalidateView();
  }
  /**
     * 挂载歌词组件到UI界面
     * @param container div容器元素或容器元素的id
     * @param config 设置字体颜色大小
     * {
        highLightFontColor: string;
        defaultFontColor: string;
        highLightFontSize: number;
        defaultFontSize: number;
      }
     */
  mount(container, config) {
    if (typeof container === "string") {
      container = document.getElementById(container);
    }
    if (container) {
      this.container = container;
      this.container.append(this.showBox);
    } else {
      throw "container not found";
    }
    const {
      highLightFontColor,
      defaultFontColor,
      highLightFontSize,
      defaultFontSize,
      ratioPositionFromTop
    } = config;
    this.mHighLightColor = highLightFontColor || this.mHighLightColor;
    this.mDefaultColor = defaultFontColor || this.mDefaultColor;
    this.highLightFontSize = highLightFontSize || this.highLightFontSize;
    this.defaultFontSize = defaultFontSize || this.defaultFontSize;
    this.__fraction = isNaN(ratioPositionFromTop)
      ? this.__fraction
      : ratioPositionFromTop;
    this.updateStyle();
  }
  /**
   * 设置默认字体样式
   * @param style 示例: "text-align:center;"
   */
  setCustomDefaultFontStyle(style) {
    this.customDefaultFontStyle = style;
  }
  /**
   * 设置高亮字体样式
   * @param style 示例: "text-align:center;"
   */
  setCustomHighLightFontStyle(style) {
    this.customHighLightFontStyle = style;
  }
  /**
   * 设置行样式
   * @param style 示例: "text-align:center;"
   */
  setCustomLineStyle(style) {
    this.customLineStyle = style;
  }
  updateStyle() {
    const styleEl = document.getElementById(`${this.id}_style`);
    if (!styleEl) return;
    styleEl.innerText = `
#${this.id} .zg-lrc-line {
  position: relative;
  top: 8px;
  display: -webkit-box;
  -webkit-box-orient: horizontal;
  -webkit-box-align: center;
  padding: 0;
  font: normal normal bold ${this.defaultFontSize}px 微软雅黑, sans-serif;
  color: ${this.mDefaultColor};
  ${this.customLineStyle}
}
#${this.id} .zg-lrc-line.zg-lrc-line-active {
  color: ${this.mHighLightColor};
  font-size: ${this.highLightFontSize}px;
  ${this.mode !== HIGH_LIGHT_MODE.KRC ? this.customHighLightFontStyle : ""}
}
#${this.id} .zg-lrc-line.zg-lrc-line-active .zg-lrc-word {
  ${this.mode === HIGH_LIGHT_MODE.KRC ? this.customHighLightFontStyle : ""}
}

#${this.id} .zg-lrc-line {
  ${this.mode !== HIGH_LIGHT_MODE.KRC ? this.customDefaultFontStyle : ""}
}
#${this.id} .zg-lrc-line .zg-lrc-word {
  background-image: -webkit-linear-gradient(left, ${this.mHighLightColor} 0%, ${
      this.mDefaultColor
    } 0%);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  margin-right: 2px;
  ${this.mode === HIGH_LIGHT_MODE.KRC ? this.customDefaultFontStyle : ""}
}
    `;
  }
  get lines() {
    let _a;
    return (
      ((_a = this.mLyricInfo) === null || _a === void 0 ? void 0 : _a.lines) ||
      []
    );
  }
  /**
   * 设置当前时间显示位置
   *
   * @param current 时间戳
   */
  setCurrentTimeMillis(currentTime) {
    this.mCurrentTimeMillis = currentTime;
    // invalidateView();
    this.renderKrcView(currentTime);
  }
  setLineActive(lineIndex, active = true) {
    const activeClass = "zg-lrc-line-active";
    const wordElement = document.querySelector(
      `#${this.id} .zg-lrc-line.zg-lrc-line-${lineIndex}`
    );
    const lastActiveWordElement = document.querySelectorAll(
      `#${this.id} .zg-lrc-line.${activeClass}`
    );
    lastActiveWordElement.forEach(item => {
      if (item && item !== wordElement) item.classList.remove(activeClass);
    });
    if (wordElement) {
      if (active) {
        if (!wordElement.classList.contains(activeClass))
          wordElement.classList.add(activeClass);
      }
    }
    return wordElement || undefined;
  }
  setWordColor(lineIndex, wordIndex, progress) {
    const wordElement = document.querySelector(
      `#${this.id} .zg-lrc-line.zg-lrc-line-${lineIndex} .zg-lrc-word.zg-lrc-word-${wordIndex}`
    );
    if (wordElement) {
      const bg =
        `-webkit-linear-gradient(left, ${this.mHighLightColor} ` +
        progress +
        `%, ${this.mDefaultColor} 0%)`;
      if (wordElement.style.backgroundImage !== bg) {
        wordElement.style.backgroundImage = bg;
      }
    }
    return wordElement || undefined;
  }
  /**
   * 处理单个字元素
   * @param lineIndex 行数索引
   * @param wordIndex 单字索引
   * @param _process 当前变化元素的进度（0-100）
   * @param pos 对该元素进行处理时间点，在哪个timeout点处理
   * @param count timeout的次数
   * @returns
   */
  renderKrcView(currentTime) {
    const lastTime = this.currentTime;
    this.lines.forEach((lineItem, lineIndex) => {
      if (!lineItem.duration && lineItem.end_time) {
        lineItem.duration = lineItem.end_time - lineItem.begin_time;
      }
      const isKrc = this.mode === HIGH_LIGHT_MODE.KRC && lineItem.words;
      const endTime =
        lineItem.begin_time +
        ((lineItem === null || lineItem === void 0
          ? void 0
          : lineItem.duration) || 0);
      if (lineItem.begin_time <= currentTime) {
        if (currentTime < endTime) {
          // 处在当前行
          this.scrollToLine(lineIndex);
          const offset = currentTime - lineItem.begin_time;
          isKrc &&
            lineItem.words.forEach((wordItem, wordIndex) => {
              const wordEndTime = wordItem.offset + wordItem.duration;
              if (wordItem.offset <= offset) {
                if (offset < wordEndTime) {
                  // 处在当前字
                  const wordOffset = offset - wordItem.offset;
                  const percent =
                    wordItem.duration === 0
                      ? 100
                      : Math.round((wordOffset / wordItem.duration) * 100);
                  this.setWordColor(lineIndex, wordIndex, percent);
                } else {
                  this.setWordColor(lineIndex, wordIndex, 100);
                }
              } else {
                this.setWordColor(lineIndex, wordIndex, 0);
              }
            });
        } else {
          // 该行已完成
          if (endTime < lastTime && lastTime < currentTime) {
            isKrc &&
              lineItem.words.forEach((wordItem, wordIndex) => {
                this.setWordColor(lineIndex, wordIndex, 100);
              });
          }
        }
      } else {
        // 未到该行
        if (lastTime > lineItem.begin_time) {
          // 清除之前走过的进度
          isKrc &&
            lineItem.words.forEach((wordItem, wordIndex) => {
              this.setWordColor(lineIndex, wordIndex, 0);
            });
        }
      }
    });
    this.currentTime = currentTime;
  }
  /**
   * 判断是否可以进行滑动
   */
  isScrollable() {
    return (
      this.mLyricInfo != null &&
      this.mLyricInfo.lines != null &&
      this.mLyricInfo.lines.length > 0
    );
  }
  /**
   * 当前歌词行（lineno）滚动
   */
  scrollToLine(lineIndex) {
    const __lis = this.lines;
    // const _timer = setTimeout(this.scrollToLine.bind(this, lineIndex + 1), _time);
    const __fraction = this.__fraction; // 高亮显示行在歌词显示区域中的固定位置百分比
    // 高亮下一行歌词
    // if (lineIndex > 0) {
    //   this.setLineActive(lineIndex, false);
    //   this.setLineActive(lineIndex - 1, false);
    // }
    const _ep = this.setLineActive(lineIndex, true);
    if (!_ep) return;
    const showBox = this.showBox;
    if (lineIndex === this.currentLine) {
      return;
    } else {
      this.currentLine = lineIndex;
    }
    // 满足需求5，6
    let _scrollTop;
    const offsetTop = _ep.offsetTop - this.lyricsUl.offsetTop;
    // console.log("offsetTop", offsetTop, _ep.offsetTop, this.lyricsUl.offsetTop);
    if (offsetTop < showBox.clientHeight * __fraction) {
      _scrollTop = 0;
    } else if (
      offsetTop >
      showBox.scrollHeight - showBox.clientHeight * (1 - __fraction)
    ) {
      _scrollTop = showBox.scrollHeight - showBox.clientHeight;
    } else {
      _scrollTop = offsetTop - showBox.clientHeight * __fraction;
    }
    // 如用户拖动滚动条导致当前显示行超出显示区域范围，下一行直接定位到当前显示行
    if (
      showBox.scrollTop - _scrollTop + showBox.clientHeight * __fraction >
        200 ||
      _scrollTop - (showBox.scrollTop + showBox.clientHeight * __fraction) > 200
    ) {
      showBox.scrollTop = _scrollTop;
    } else {
      let lastLineDuration;
      if (lineIndex === 0) {
        lastLineDuration = __lis[lineIndex].begin_time;
      } else {
        lastLineDuration =
          __lis[lineIndex].begin_time - __lis[lineIndex - 1].begin_time;
      }
      // 单行滚动
      // 获取滚动步长
      const step = Math.ceil(
        Math.abs(showBox.scrollTop - _scrollTop) /
          (lastLineDuration / this.__freq)
      );
      this.scrollBox(showBox.scrollTop, _scrollTop, step);
    }
  }
  /**
   * 歌词单行滚动实现
   */
  scrollBox(current, dest, step) {
    if (Math.abs(current - dest) < step) {
      return;
    }
    const showBox = this.showBox;
    if (current < dest) {
      showBox.scrollTop += step;
      current += step;
    } else {
      showBox.scrollTop -= step;
      current -= step;
    }
    setTimeout(this.scrollBox.bind(this, current, dest, step), this.__freq);
  }
}
ZegoLyricView.TAG = "ZegoLyricView";

window.ZegoLyricView = ZegoLyricView;
